<?php

namespace pam\Mapper;

/**
 * Description of PolicyDataAccess
 *
 * @author Robert Bwana
 */
use pam\Mapper\PolicyDataAccessInterface;
use Zend\Db\Adapter\AdapterInterface;
use pam\Model\PolicyGoal;
use pam\Model\Policy;
use Zend\Db\Sql\Sql;
use Zend\Db\Sql\Insert;
use Zend\Db\Sql\Update;
use Zend\Db\Sql\Delete;
use Zend\Db\Adapter\Driver\ResultInterface;
use Zend\Db\ResultSet\HydratingResultSet;
use Zend\Stdlib\Hydrator\HydratorInterface;

class PolicyDataAccess {

    protected $dbAdapter;
    protected $hydrator;
    protected $policy;
    protected $policyGoal;
    protected $table;
    protected $secondary_table;

    public function __construct(AdapterInterface $dbAdapter, HydratorInterface $hydrator, Policy $policy, PolicyGoal $policyGoal) {
        $this->dbAdapter = $dbAdapter;
        $this->hydrator = $hydrator;
        $this->policy = $policy;
        $this->policyGoal = $policyGoal;
        $this->table = 'pam_policy';
        $this->secondary_table = 'pam_policygoals';
    }

    public function delete($id) {
        $action = new Delete($this->secondary_table);
        $action->where(array(
            'policy_id = ?' => $id
        ));

        $sql = new Sql($this->dbAdapter);
        $stmt = $sql->prepareStatementForSqlObject($action);
        $result = $stmt->execute();

        $action = new Delete($this->table);
        $action->where(array(
            'id = ?' => $id
        ));

        $stmt = $sql->prepareStatementForSqlObject($action);
        $result = $stmt->execute();

        return (bool) $result->getAffectedRows();
    }

    /*
     * returns SocialPolicy
     */

    public function find($id) {
        $sql = new Sql($this->dbAdapter);
        $select = $sql->select($this->table);
        $select->where(array('id = ?' => $id));

        $stmt = $sql->prepareStatementForSqlObject($select);
        $result = $stmt->execute();

        if ($result instanceof ResultInterface && $result->isQueryResult() && $result->getAffectedRows()) {
            return $this->hydrator->hydrate($result->current(), $this->policy);
        } else {
            throw new \InvalidArgumentException("Policy with given ID:{$id} not found.");
        }
    }

    public function findPolicyGoals($policyId) {
        $sql = new Sql($this->dbAdapter);
        $select = $sql->select($this->secondary_table);
        $select->where(array('policy_id = ?' => $policyId));

        $stmt = $sql->prepareStatementForSqlObject($select);
        $result = $stmt->execute();

        if ($result instanceof ResultInterface && $result->isQueryResult() && $result->getAffectedRows()) {

            $resultSet = new HydratingResultSet($this->hydrator, $this->policyGoal);
            return $resultSet->initialize($result);

        } else {

            return array();
        }
    }

    public function save(Policy $policy) {
        $policyData = $this->hydrator->extract($policy);
        unset($policyData['id']);

        if ($policy->getId()) {
            $action = new Update($this->table);
            $action->set($policyData);
            $action->where(array('id = ?' => $policy->getId()));
        } else {
            $action = new Insert($this->table);
            $action->values($policyData);
        }

        $sql = new Sql($this->dbAdapter);
        $stmt = $sql->prepareStatementForSqlObject($action);
        $result = $stmt->execute();

        if ($result instanceof ResultInterface) {
            if ((bool) $newId = $result->getGeneratedValue()) {
                $policy->setId($newId);
            }

            return $policy;
        }
    }

    public function saveGoals(array $goals) {
        foreach ($goals as $goal){
        $goalData = $this->hydrator->extract($goal);
        unset($goalData['id']);

        if ($goal->getId()) {
            $action = new Update($this->table);
            $action->set($goalData);
            $action->where(array('id = ?' => $goal->getId()));
        } else {
            $action = new Insert($this->table);
            $action->values($goalData);
        }

        $sql = new Sql($this->dbAdapter);
        $stmt = $sql->prepareStatementForSqlObject($action);
        $result = $stmt->execute();
        
        if ($result instanceof ResultInterface) {
            if ((bool) $newId = $result->getGeneratedValue()) {
                $goal->setId($newId);
            }            
        }
        }
        return $goals;
                
    }

}
